package com.tabjin.rfidsocket.service.sys.impl;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.tabjin.rfidsocket.common.RequestHolder;
import com.tabjin.rfidsocket.common.utils.BeanValidator;
import com.tabjin.rfidsocket.exception.ParamException;
import com.tabjin.rfidsocket.mapper.mapper.*;
import com.tabjin.rfidsocket.pojo.SysRole;
import com.tabjin.rfidsocket.pojo.SysRoleAcl;
import com.tabjin.rfidsocket.pojo.bo.SysRoleBO;
import com.tabjin.rfidsocket.pojo.vo.SysRoleAclVO;
import com.tabjin.rfidsocket.pojo.vo.SysRoleVO;
import com.tabjin.rfidsocket.pojo.vo.SysUserVO;
import com.tabjin.rfidsocket.service.sys.SysRoleService;
import com.tabjin.rfidsocket.utils.IpUtil;
import org.apache.shiro.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author tabjin
 * create at 2020/12/24 00:30
 * @program rfid_socket
 * @description
 */
@Service
public class SysRoleServiceImpl implements SysRoleService {

    static final Logger logger = LoggerFactory.getLogger(SysRoleServiceImpl.class);

    private final SysRoleMapper sysRoleMapper;
    private final SysRoleCustomMapper sysRoleCustomMapper;
    private final SysRoleUserCustomMapper sysRoleUserCustomMapper;
    private final SysRoleAclCustomMapper sysRoleAclCustomMapper;
    private final SysUserMapper sysUserMapper;
    private final SysUserCustomMapper sysUserCustomMapper;

    public SysRoleServiceImpl(SysRoleMapper sysRoleMapper, SysRoleCustomMapper sysRoleCustomMapper, SysRoleUserCustomMapper sysRoleUserCustomMapper, SysRoleAclCustomMapper sysRoleAclCustomMapper, SysUserMapper sysUserMapper, SysUserCustomMapper sysUserCustomMapper) {
        this.sysRoleMapper = sysRoleMapper;
        this.sysRoleCustomMapper = sysRoleCustomMapper;
        this.sysRoleUserCustomMapper = sysRoleUserCustomMapper;
        this.sysRoleAclCustomMapper = sysRoleAclCustomMapper;
        this.sysUserMapper = sysUserMapper;
        this.sysUserCustomMapper = sysUserCustomMapper;
    }

    /**
     * 新增角色
     *
     * @param sysRoleBO 角色对象BO
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public SysRoleVO add(SysRoleBO sysRoleBO) {
//        BeanValidator.check(sysRoleBO);
        if (checkExist(sysRoleBO.getName(), sysRoleBO.getId())) {
            logger.error("新增角色 存在相同的角色名");
            throw new ParamException("新增角色 存在相同的角色名");
        }

        SysRole sysRole = SysRole.builder()
                .name(sysRoleBO.getName())
                .type(sysRoleBO.getType())
                .seq(sysRoleBO.getSeq())
                .status(sysRoleBO.getStatus())
                .remark(sysRoleBO.getRemark())
                .build();
        sysRole.setOperator(RequestHolder.getCurrentUser().getUsername());
        sysRole.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()));
        sysRole.setOperateTime(new Date());

        Integer i = sysRoleMapper.insertSelective(sysRole);

        SysRoleVO vo = new SysRoleVO();
        BeanUtils.copyProperties(sysRole, vo);
        return vo;
    }

    /**
     * 更新角色
     *
     * @param sysRoleBO 角色对象BO
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public SysRoleVO update(SysRoleBO sysRoleBO) {
        BeanValidator.check(sysRoleBO);
        if (checkExist(sysRoleBO.getName(), sysRoleBO.getId())) {
            logger.error("存在相同的角色名");
            throw new ParamException("存在相同的角色名");
        }

        SysRole before = sysRoleMapper.selectByPrimaryKey(sysRoleBO.getId());
        Preconditions.checkNotNull(before, "待更新的角色不存在");

        SysRole after = SysRole.builder()
                .id(sysRoleBO.getId())
                .name(sysRoleBO.getName())
                .type(sysRoleBO.getType())
                .seq(sysRoleBO.getSeq())
                .status(sysRoleBO.getStatus())
                .remark(sysRoleBO.getRemark())
                .build();
        after.setOperator(RequestHolder.getCurrentUser().getUsername());
        after.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()));
        after.setOperateTime(new Date());

        Integer i = sysRoleMapper.updateByPrimaryKeySelective(after);

        SysRoleVO vo = new SysRoleVO();
        BeanUtils.copyProperties(after, vo);
        return vo;
    }

    /**
     * 获取所有角色
     *
     * @param name 角色名
     * @param id   角色id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<SysRoleVO> getAll(String name, Integer id) {
//        return sysRoleCustomMapper.getAll(name, id);
        return sysRoleCustomMapper.getAll();
//        return sysRoleCustomMapper.selectAll();
    }

    /**
     * 获取指定用户的角色列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<SysRoleVO> getRoleListByUserId(Integer userId) {
        List<Integer> roleIdList = sysRoleUserCustomMapper.getRoleIdListByUserId(userId);
        if (CollectionUtils.isEmpty(roleIdList)) {
            return Lists.newArrayList();
        }
        return sysRoleCustomMapper.getByIdList(roleIdList);
    }

    /**
     * 获取指定权限点的角色列表
     *
     * @param aclId
     * @return
     */
    @Override
    public List<SysRoleVO> getRoleListByAclId(Integer aclId) {
        List<Integer> roleIdList = sysRoleAclCustomMapper.getRoleIdListByAclId(aclId);
        if (CollectionUtils.isEmpty(roleIdList)) {
            return Lists.newArrayList();
        }
        return sysRoleCustomMapper.getByIdList(roleIdList);
    }

    /**
     * 获取指定角色的用户列表
     *
     * @param roleList
     * @return
     */
    @Override
    public List<SysUserVO> getUserListByRoleList(List<SysRoleVO> roleList) {
        if (CollectionUtils.isEmpty(roleList)) {
            return Lists.newArrayList();
        }
        List<Integer> roleIdList = roleList.stream().map(sysRoleVO -> sysRoleVO.getId()).collect(Collectors.toList());
        List<Integer> userIdList = sysRoleUserCustomMapper.getUserIdListByRoleIdList(roleIdList);
        if (CollectionUtils.isEmpty(userIdList)) {// 如果这些角色没有分配用户
            return Lists.newArrayList();
        }
        // 获取到用户
        return sysUserCustomMapper.getUserByUserIdList(userIdList);
    }

    /**
     * 校验是否存在相同角色名
     *
     * @param roleName 角色名
     * @param roleId   角色id
     * @return
     */
    private boolean checkExist(String roleName, Integer roleId) {
//        Example example = new Example(SysRole.class);
//        Example.Criteria criteria = example.createCriteria();
//        criteria.andEqualTo("name", roleName);
//        if (roleId != null) {
//            criteria.andNotEqualTo("roleId", roleId);
//        }
//        return sysRoleMapper.selectCountByExample(example) > 0;

        return sysRoleCustomMapper.countByName(roleName, roleName) > 0;
    }
}
